<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>XTSRunner - Web控制台</title>
    <link rel="icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
    <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" type="image/x-icon">
    <style>
        body {
            font-family: Arial, sans-serif;
            margin: 0;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            max-width: 1600px;
            margin: 0 auto;
            background-color: white;
            padding: 20px;
            border-radius: 5px;
            box-shadow: 0 2px 5px rgba(0,0,0,0.1);
        }
        h1 {
            color: #333;
            border-bottom: 1px solid #eee;
            padding-bottom: 10px;
            margin-bottom: 20px;
        }
        
        /* 测试单元容器 - 垂直排列 */
        .test-units-container {
            display: flex;
            flex-direction: column;
            gap: 20px;
        }
        
        /* 单个测试单元 */
        .test-unit {
            width: 100%;
            background-color: #f9f9f9;
            border-radius: 5px;
            padding: 15px;
            box-shadow: 0 1px 3px rgba(0,0,0,0.1);
            display: flex;
            flex-direction: column;
            position: relative;
        }
        
        /* 控制面板样式 */
        .control-panel {
            display: flex;
            flex-direction: column;
            gap: 10px;
            margin-bottom: 15px;
            padding: 10px;
            background-color: #f0f0f0;
            border-radius: 5px;
        }
        
        .form-group {
            margin-bottom: 10px;
        }
        
        label {
            display: block;
            margin-bottom: 5px;
            font-weight: bold;
            font-size: 14px;
        }
        
        select, button {
            padding: 6px 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 14px;
            width: 100%;
        }
        
        button {
            background-color: #4CAF50;
            color: white;
            border: none;
            cursor: pointer;
            transition: background-color 0.3s;
            margin-top: 5px;
        }
        
        button:hover {
            background-color: #45a049;
        }
        
        button:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
        }
        
        /* 进度条样式 */
        .progress-bar {
            height: 15px;
            background-color: #e0e0e0;
            border-radius: 10px;
            margin-top: 10px;
            overflow: hidden;
        }
        
        .progress-fill {
            height: 100%;
            background-color: #4CAF50;
            width: 0%;
            transition: width 0.5s, background-color 0.5s;
        }
        
        .progress-fill.inactive {
            background-color: #a0a0a0;
        }
        
        /* 日志容器样式 */
        .log-container {
            flex: 1;
            min-height: 250px;
            max-height: 400px;
            overflow-y: auto;
            background-color: #2b2b2b;
            color: #f8f8f2;
            padding: 10px;
            border-radius: 5px;
            font-family: monospace;
            font-size: 12px;
            margin-top: 10px;
            transition: max-height 0.3s ease;
        }
        
        .log-container.expanded {
            max-height: 800px;
        }
        
        .log-line {
            margin: 0;
            padding: 2px 0;
            white-space: pre-wrap;
            word-wrap: break-word;
        }
        
        .log-controls {
            display: flex;
            justify-content: space-between;
            margin-top: 10px;
            margin-bottom: 5px;
        }
        
        .log-controls-buttons {
            display: flex;
            gap: 10px;
        }
        
        .log-controls button {
            background-color: #007bff;
            padding: 5px 10px;
            font-size: 12px;
            width: auto;
        }
        
        .log-controls button:hover {
            background-color: #0056b3;
        }
        
        .log-controls button.clear-log-btn {
            background-color: #dc3545;
        }
        
        .log-controls button.clear-log-btn:hover {
            background-color: #c82333;
        }
        
        .auto-scroll-toggle {
            display: flex;
            align-items: center;
            gap: 5px;
            font-size: 12px;
        }
        
        .auto-scroll-toggle input {
            margin: 0;
        }
        
        /* 状态信息 */
        .status-info {
            margin: 10px 0;
            font-size: 14px;
        }
        
        .status-info p {
            margin: 5px 0;
        }
        
        /* 停止按钮 */
        .stop-btn {
            background-color: #f44336;
            margin-top: 10px;
        }
        
        .stop-btn:hover {
            background-color: #d32f2f;
        }
        
        /* 测试单元标题 */
        .unit-title {
            font-weight: bold;
            font-size: 16px;
            margin-bottom: 10px;
            text-align: center;
            border-bottom: 1px solid #ddd;
            padding-bottom: 5px;
        }
        
        /* 响应式布局 */
        @media (max-width: 1200px) {
            .test-units-container {
                flex-direction: column;
            }
            
            .test-unit {
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>XTSRunner - Web控制台</h1>
        
        <div class="unit-controls" style="margin-bottom: 20px; display: flex; gap: 10px;">
            <button id="add-unit-btn" class="control-btn">+ 添加测试单元</button>
            <button id="remove-unit-btn" class="control-btn" disabled>- 删除测试单元</button>
        </div>
        
        <div class="test-units-container">
            <!-- 测试单元1 - 默认显示 -->
            <div class="test-unit" id="test-unit-1" style="display: block;">
                <div class="unit-title">测试单元 1</div>
                
                <div class="control-panel">
                    <div class="form-group">
                        <label for="repo-type-1">仓库组:</label>
                        <select id="repo-type-1" class="repo-type">
                            <option value="openharmony-sig">openharmony-sig</option>
                            <option value="openharmony-tpc">openharmony-tpc</option>
                            <option value="openharmony_tpc_samples">openharmony_tpc_samples</option>
                            <option value="specific">搜索特定库</option>
                        </select>
                    </div>

                    <!-- 添加搜索库的表单，默认隐藏 -->
                    <div class="form-group search-lib-form" id="search-lib-form-1" style="display: none;">
                        <label for="search-term-1">搜索库:</label>
                        <div style="display: flex; gap: 5px;">
                            <input type="text" id="search-term-1" class="search-term" placeholder="输入库名关键词">
                            <button class="search-btn" data-unit-id="1">搜索</button>
                        </div>
                        <div class="search-results" id="search-results-1" style="display: none; margin-top: 10px; max-height: 150px; overflow-y: auto;">
                            <!-- 搜索结果将在这里显示 -->
                        </div>
                        <input type="hidden" id="selected-lib-1" class="selected-lib">
                    </div>
                    
                    <div class="form-group">
                        <label for="sdk-version-1">SDK版本:</label>
                        <select id="sdk-version-1" class="sdk-version">
                            <option value="5.0.0">5.0.0</option>
                            <option value="5.0.1">5.0.1</option>
                            <option value="5.0.2">5.0.2</option>
                            <option value="5.0.3">5.0.3</option>
                            <option value="5.0.4" selected>5.0.4</option>
                            <option value="5.0.5">5.0.5</option>
                            <option value="5.1.0">5.1.0</option>
                        </select>
                    </div>
                    
                    <div class="form-group">
                        <label for="release-mode-1">编译模式:</label>
                        <select id="release-mode-1" class="release-mode">
                            <option value="n">Debug模式</option>
                            <option value="y">Release模式</option>
                        </select>
                    </div>
                    
                    <button class="start-btn" data-unit-id="1">开始测试</button>
                </div>
                
                <div class="status-info" style="display: none;">
                    <p><strong>仓库组:</strong> <span class="status-repo-type">-</span></p>
                    <p><strong>进度:</strong> <span class="status-progress">0/0</span></p>
                    <p><strong>当前库:</strong> <span class="status-current-lib">-</span></p>
                    <div class="progress-bar">
                        <div class="progress-fill"></div>
                    </div>
                    <button class="stop-btn" style="display: none;">停止测试</button>
                </div>
                
                <div class="log-controls" style="display: none;">
                    <div class="auto-scroll-toggle">
                        <input type="checkbox" class="auto-scroll" checked>
                        <label>自动滚动日志</label>
                    </div>
                    <div class="log-controls-buttons">
                        <button class="clear-log-btn">清理日志</button>
                        <button class="download-log-btn">下载日志</button>
                        <button class="expand-log-btn">放大日志</button>
                    </div>
                </div>
                
                <div class="log-container" style="display: none;">
                    <p class="log-line">等待测试开始...</p>
                </div>
            </div>
            
            <!-- 测试单元2 - 默认隐藏 -->
            <div class="test-unit" id="test-unit-2" style="display: none;">
                <div class="unit-title">测试单元 2</div>
                
                <div class="control-panel">
                    <div class="form-group">
                        <label for="repo-type-2">仓库组:</label>
                        <select id="repo-type-2" class="repo-type">
                            <option value="openharmony-sig">openharmony-sig</option>
                            <option value="openharmony-tpc">openharmony-tpc</option>
                            <option value="openharmony_tpc_samples">openharmony_tpc_samples</option>
                            <option value="specific">搜索特定库</option>
                        </select>
                    </div>

                    <!-- 添加搜索库的表单，默认隐藏 -->
                    <div class="form-group search-lib-form" id="search-lib-form-2" style="display: none;">
                        <label for="search-term-2">搜索库:</label>
                        <div style="display: flex; gap: 5px;">
                            <input type="text" id="search-term-2" class="search-term" placeholder="输入库名关键词">
                            <button class="search-btn" data-unit-id="2">搜索</button>
                        </div>
                        <div class="search-results" id="search-results-2" style="display: none; margin-top: 10px; max-height: 150px; overflow-y: auto;">
                            <!-- 搜索结果将在这里显示 -->
                        </div>
                        <input type="hidden" id="selected-lib-2" class="selected-lib">
                    </div>
                    
                    <div class="form-group">
                        <label for="sdk-version-2">SDK版本:</label>
                        <select id="sdk-version-2" class="sdk-version">
                            <option value="5.0.0">5.0.0</option>
                            <option value="5.0.1">5.0.1</option>
                            <option value="5.0.2">5.0.2</option>
                            <option value="5.0.3">5.0.3</option>
                            <option value="5.0.4" selected>5.0.4</option>
                            <option value="5.1.0">5.1.0</option>
                        </select>
                    </div>
                    
                    <div class="form-group">
                        <label for="release-mode-2">编译模式:</label>
                        <select id="release-mode-2" class="release-mode">
                            <option value="n">Debug模式</option>
                            <option value="y">Release模式</option>
                        </select>
                    </div>
                    
                    <button class="start-btn" data-unit-id="2">开始测试</button>
                </div>
                
                <div class="status-info" style="display: none;">
                    <p><strong>仓库组:</strong> <span class="status-repo-type">-</span></p>
                    <p><strong>进度:</strong> <span class="status-progress">0/0</span></p>
                    <p><strong>当前库:</strong> <span class="status-current-lib">-</span></p>
                    <div class="progress-bar">
                        <div class="progress-fill"></div>
                    </div>
                    <button class="stop-btn" style="display: none;">停止测试</button>
                </div>
                
                <div class="log-controls" style="display: none;">
                    <div class="auto-scroll-toggle">
                        <input type="checkbox" class="auto-scroll" checked>
                        <label>自动滚动日志</label>
                    </div>
                    <div class="log-controls-buttons">
                        <button class="clear-log-btn">清理日志</button>
                        <button class="download-log-btn">下载日志</button>
                    </div>
                </div>
                
                <div class="log-container" style="display: none;">
                    <p class="log-line">等待测试开始...</p>
                </div>
            </div>
            
            <!-- 测试单元3 - 默认隐藏 -->
            <div class="test-unit" id="test-unit-3" style="display: none;">
                <div class="unit-title">测试单元 3</div>
                
                <div class="control-panel">
                    <div class="form-group">
                        <label for="repo-type-3">仓库组:</label>
                        <select id="repo-type-3" class="repo-type">
                            <option value="openharmony-sig">openharmony-sig</option>
                            <option value="openharmony-tpc">openharmony-tpc</option>
                            <option value="openharmony_tpc_samples">openharmony_tpc_samples</option>
                            <option value="specific">搜索特定库</option>
                        </select>
                    </div>

                    <!-- 添加搜索库的表单，默认隐藏 -->
                    <div class="form-group search-lib-form" id="search-lib-form-3" style="display: none;">
                        <label for="search-term-3">搜索库:</label>
                        <div style="display: flex; gap: 5px;">
                            <input type="text" id="search-term-3" class="search-term" placeholder="输入库名关键词">
                            <button class="search-btn" data-unit-id="3">搜索</button>
                        </div>
                        <div class="search-results" id="search-results-3" style="display: none; margin-top: 10px; max-height: 150px; overflow-y: auto;">
                            <!-- 搜索结果将在这里显示 -->
                        </div>
                        <input type="hidden" id="selected-lib-3" class="selected-lib">
                    </div>
                    
                    <div class="form-group">
                        <label for="sdk-version-3">SDK版本:</label>
                        <select id="sdk-version-3" class="sdk-version">
                            <option value="5.0.0">5.0.0</option>
                            <option value="5.0.1">5.0.1</option>
                            <option value="5.0.2">5.0.2</option>
                            <option value="5.0.3">5.0.3</option>
                            <option value="5.0.4" selected>5.0.4</option>
                            <option value="5.1.0">5.1.0</option>
                        </select>
                    </div>
                    
                    <div class="form-group">
                        <label for="release-mode-3">编译模式:</label>
                        <select id="release-mode-3" class="release-mode">
                            <option value="n">Debug模式</option>
                            <option value="y">Release模式</option>
                        </select>
                    </div>
                    
                    <button class="start-btn" data-unit-id="3">开始测试</button>
                </div>
                
                <div class="status-info" style="display: none;">
                    <p><strong>仓库组:</strong> <span class="status-repo-type">-</span></p>
                    <p><strong>进度:</strong> <span class="status-progress">0/0</span></p>
                    <p><strong>当前库:</strong> <span class="status-current-lib">-</span></p>
                    <div class="progress-bar">
                        <div class="progress-fill"></div>
                    </div>
                    <button class="stop-btn" style="display: none;">停止测试</button>
                </div>
                
                <div class="log-controls" style="display: none;">
                    <div class="auto-scroll-toggle">
                        <input type="checkbox" class="auto-scroll" checked>
                        <label>自动滚动日志</label>
                    </div>
                    <div class="log-controls-buttons">
                        <button class="clear-log-btn">清理日志</button>
                        <button class="download-log-btn">下载日志</button>
                    </div>
                </div>
                
                <div class="log-container" style="display: none;">
                    <p class="log-line">等待测试开始...</p>
                </div>
            </div>
        </div>
    </div>
    
    <style>
        .control-btn {
            padding: 5px 10px;
            background-color: #4285f4;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            transition: background-color 0.3s;
        }
        
        .control-btn:hover {
            background-color: #3367d6;
        }
        
        .control-btn:disabled {
            background-color: #cccccc;
            cursor: not-allowed;
        }
    </style>
    
    <script>
        document.addEventListener('DOMContentLoaded', function() {
            // 单元控制逻辑
            const addUnitBtn = document.getElementById('add-unit-btn');
            const removeUnitBtn = document.getElementById('remove-unit-btn');
            let activeUnits = 1;
            
            // 添加单元按钮点击事件
            addUnitBtn.addEventListener('click', function() {
                if (activeUnits >= 3) {
                    alert('最多只能创建3个测试单元');
                    return;
                }
                
                // 显示下一个单元
                activeUnits++;
                document.getElementById(`test-unit-${activeUnits}`).style.display = 'block';
                
                // 更新按钮状态
                if (activeUnits >= 3) {
                    addUnitBtn.disabled = true;
                }
                removeUnitBtn.disabled = false;
            });
            
            // 删除单元按钮点击事件
            removeUnitBtn.addEventListener('click', function() {
                if (activeUnits <= 1) {
                    return;
                }
                
                // 隐藏当前单元
                document.getElementById(`test-unit-${activeUnits}`).style.display = 'none';
                activeUnits--;
                
                // 更新按钮状态
                if (activeUnits <= 1) {
                    removeUnitBtn.disabled = true;
                }
                addUnitBtn.disabled = false;
            });
            
            // 存储所有测试单元的状态
            const testUnits = {
                1: { processId: null, running: false, logIndex: 0, autoScroll: true, intervalId: null },
                2: { processId: null, running: false, logIndex: 0, autoScroll: true, intervalId: null },
                3: { processId: null, running: false, logIndex: 0, autoScroll: true, intervalId: null }
            };
            
            // 监听仓库组选择变化
            document.querySelectorAll('.repo-type').forEach(select => {
                select.addEventListener('change', function() {
                    const unitId = this.id.split('-').pop();
                    const searchForm = document.getElementById(`search-lib-form-${unitId}`);
                    
                    if (this.value === 'specific') {
                        // 显示搜索表单
                        searchForm.style.display = 'block';
                    } else {
                        // 隐藏搜索表单
                        searchForm.style.display = 'none';
                        // 清空已选库
                        document.getElementById(`selected-lib-${unitId}`).value = '';
                    }
                });
            });
            
            // 定义搜索库的函数，以便可以重复使用
            function setupSearchLibraryHandler(button) {
                button.addEventListener('click', function() {
                    const unitId = this.getAttribute('data-unit-id');
                    const searchTerm = document.querySelector(`#test-unit-${unitId} .search-term`).value.trim();
                    const resultsContainer = document.querySelector(`#test-unit-${unitId} .search-results`);
                    
                    if (!searchTerm) {
                        alert('请输入搜索关键词');
                        return;
                    }
                    
                    // 显示加载中
                    resultsContainer.innerHTML = '<p>搜索中...</p>';
                    resultsContainer.style.display = 'block';
                    
                    // 发送搜索请求
                    fetch('/api/search_libraries', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ search_term: searchTerm }),
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data.status === 'success') {
                            if (data.count === 0) {
                                resultsContainer.innerHTML = '<p>未找到匹配的库</p>';
                            } else {
                                // 显示搜索结果
                                let html = `<p>找到 ${data.count} 个匹配的库:</p>`;
                                html += '<div style="margin-top: 5px; max-height: 150px; overflow-y: auto;">';
                                
                                data.libraries.forEach((lib, index) => {
                                    html += `
                                    <div style="padding: 5px; border-bottom: 1px solid #eee;">
                                        <label>
                                            <input type="checkbox" name="lib-${unitId}" value="${lib}"> ${lib}
                                        </label>
                                    </div>`;
                                });
                                
                                html += '</div>';
                                html += '<button class="select-lib-btn" data-unit-id="' + unitId + '" style="margin-top: 10px;">选择库</button>';
                                
                                resultsContainer.innerHTML = html;
                                
                                // 添加选择库按钮事件
                                resultsContainer.querySelector('.select-lib-btn').addEventListener('click', function() {
                                    const selectedCheckboxes = resultsContainer.querySelectorAll(`input[name="lib-${unitId}"]:checked`);
                                    
                                    if (selectedCheckboxes.length === 0) {
                                        alert('请至少选择一个库');
                                        return;
                                    }
                                    
                                    // 获取所有选中的库
                                    const selectedLibs = Array.from(selectedCheckboxes).map(cb => cb.value);
                                    document.getElementById(`selected-lib-${unitId}`).value = selectedLibs.join(',');
                                    
                                    // 更新UI显示
                                    const searchForm = document.getElementById(`search-lib-form-${unitId}`);
                                    searchForm.innerHTML = `
                                        <label>已选择库:</label>
                                        <div style="padding: 5px; background: #e8f4e8; border-radius: 3px; margin-top: 5px;">
                                            <strong>${selectedLibs.join(', ')}</strong>
                                            <button class="change-lib-btn" data-unit-id="${unitId}" style="margin-left: 10px; padding: 2px 5px; font-size: 12px;">更改</button>
                                        </div>
                                        <input type="hidden" id="selected-lib-${unitId}" class="selected-lib" value="${selectedLibs.join(',')}">
                                    `;
                                    
                                    // 添加更改按钮事件
                                    searchForm.querySelector('.change-lib-btn').addEventListener('click', function() {
                                        const currentUnitId = this.getAttribute('data-unit-id');
                                        // 重置搜索表单
                                        searchForm.innerHTML = `
                                            <label for="search-term-${currentUnitId}">搜索库:</label>
                                            <div style="display: flex; gap: 5px;">
                                                <input type="text" id="search-term-${currentUnitId}" class="search-term" placeholder="输入库名关键词">
                                                <button class="search-btn" data-unit-id="${currentUnitId}">搜索</button>
                                            </div>
                                            <div class="search-results" id="search-results-${currentUnitId}" style="display: none; margin-top: 10px; max-height: 150px; overflow-y: auto;">
                                                <!-- 搜索结果将在这里显示 -->
                                            </div>
                                            <input type="hidden" id="selected-lib-${currentUnitId}" class="selected-lib">
                                        `;
                                        
                                        // 重新绑定搜索按钮事件
                                        setupSearchLibraryHandler(searchForm.querySelector('.search-btn'));
                                    });
                                });
                            }
                        } else {
                            resultsContainer.innerHTML = `<p>搜索出错: ${data.message}</p>`;
                        }
                    })
                    .catch(error => {
                        resultsContainer.innerHTML = `<p>请求出错: ${error.message}</p>`;
                    });
                });
            }
            
            // 初始化所有搜索按钮的事件处理
            document.querySelectorAll('.search-btn').forEach(button => {
                setupSearchLibraryHandler(button);
            });
            
            // 定义状态更新函数
            function startStatusUpdates(unitId) {
                const unit = document.getElementById(`test-unit-${unitId}`);
                const processId = testUnits[unitId].processId;
                
                // 清除之前的定时器（如果有）
                if (testUnits[unitId].intervalId) {
                    clearInterval(testUnits[unitId].intervalId);
                }
                
                // 设置新的定时器，每秒更新一次状态
                testUnits[unitId].intervalId = setInterval(() => {
                    if (!testUnits[unitId].running) {
                        clearInterval(testUnits[unitId].intervalId);
                        return;
                    }
                    
                    // 发送请求获取最新状态
                    fetch(`/api/test_status/${processId}`)
                        .then(response => response.json())
                        .then(data => {
                            if (data.status === 'success') {
                                // 更新进度信息
                                unit.querySelector('.status-progress').textContent = `${data.progress}/${data.total}`;
                                unit.querySelector('.status-current-lib').textContent = data.current_lib || '-';
                                
                                // 更新进度条
                                const progressPercent = data.total > 0 ? (data.progress / data.total) * 100 : 0;
                                unit.querySelector('.progress-fill').style.width = `${progressPercent}%`;
                                
                                // 更新日志
                                updateLogs(unitId, data.logs);
                                
                                // 如果测试已完成，重置UI
                                if (!data.running) {
                                    testUnits[unitId].running = false;
                                    clearInterval(testUnits[unitId].intervalId);
                                    unit.querySelector('.start-btn').disabled = false;
                                    unit.querySelector('.start-btn').textContent = '开始测试';
                                    
                                    // 隐藏停止按钮
                                    const stopBtn = unit.querySelector('.stop-btn');
                                    stopBtn.style.display = 'none';
                                    stopBtn.disabled = false;
                                    stopBtn.textContent = '停止测试';
                                    
                                    unit.querySelector('.progress-fill').classList.add('inactive');
                                    
                                    // 添加完成信息到日志
                                    const logContainer = unit.querySelector('.log-container');
                                    const logLine = document.createElement('p');
                                    logLine.className = 'log-line';
                                    logLine.textContent = '测试已完成';
                                    logLine.style.color = 'green';
                                    logLine.style.fontWeight = 'bold';
                                    logContainer.appendChild(logLine);
                                    
                                    if (testUnits[unitId].autoScroll) {
                                        logContainer.scrollTop = logContainer.scrollHeight;
                                    }
                                    
                                    // 重置测试状态
                                    resetTestStatus(processId);
                                }
                            }
                        })
                        .catch(error => {
                            console.error('获取测试状态出错:', error);
                        });
                }, 1000);
            }
            
            // 更新日志函数
            function updateLogs(unitId, logs) {
                const unit = document.getElementById(`test-unit-${unitId}`);
                const logContainer = unit.querySelector('.log-container');
                
                // 如果有新日志
                if (logs.length > testUnits[unitId].logIndex) {
                    // 检查是否在底部（用于决定是否保持在底部）
                    const isScrolledToBottom = logContainer.scrollHeight - logContainer.clientHeight <= logContainer.scrollTop + 5;
                    
                    // 创建文档片段，提高性能
                    const fragment = document.createDocumentFragment();
                    
                    // 添加新日志
                    for (let i = testUnits[unitId].logIndex; i < logs.length; i++) {
                        const logLine = document.createElement('p');
                        logLine.className = 'log-line';
                        
                        // 使用textContent而不是innerHTML，提高性能和安全性
                        logLine.textContent = logs[i];
                        
                        // 为特定消息添加颜色
                        if (logs[i].includes("测试和报告生成已完成") || logs[i].includes("测试进程已结束") || logs[i].includes("PASS")) {
                            logLine.style.color = "green";
                            logLine.style.fontWeight = "bold";
                        } else if (logs[i].includes("测试已被用户中断")) {
                            logLine.style.color = "orange";
                            logLine.style.fontWeight = "bold";
                        } else if (logs[i].includes("FAIL") || logs[i].includes("ERROR")) {
                            logLine.style.color = "red";
                            logLine.style.fontWeight = "bold";
                        } else if (logs[i].includes("WARNING")) {
                            logLine.style.color = "#FFA500"; // 橙色
                        } else if (logs[i].includes("INFO")) {
                            logLine.style.color = "#4682B4"; // 钢蓝色
                        }
                        
                        // 添加到文档片段
                        fragment.appendChild(logLine);
                    }
                    
                    // 一次性添加所有新日志，减少DOM操作
                    logContainer.appendChild(fragment);
                    
                    // 更新日志索引
                    testUnits[unitId].logIndex = logs.length;
                    
                    // 如果之前在底部或启用了自动滚动，则滚动到底部
                    if (isScrolledToBottom || testUnits[unitId].autoScroll) {
                        // 使用requestAnimationFrame优化滚动性能
                        requestAnimationFrame(() => {
                            logContainer.scrollTop = logContainer.scrollHeight;
                        });
                    }
                    
                    // 如果日志数量过多，考虑移除旧日志以提高性能
                    const maxLogLines = 1000; // 最大保留日志行数
                    const logLines = logContainer.querySelectorAll('.log-line');
                    if (logLines.length > maxLogLines) {
                        // 移除最旧的日志行，保留最新的maxLogLines行
                        for (let i = 0; i < logLines.length - maxLogLines; i++) {
                            logContainer.removeChild(logLines[i]);
                        }
                    }
                }
            }
            
            // 初始化日志容器的滚动事件监听
            function initLogScrollListeners() {
                document.querySelectorAll('.log-container').forEach(container => {
                    const unitId = container.closest('.test-unit').id.split('-').pop();
                    const autoScrollCheckbox = document.querySelector(`#test-unit-${unitId} .auto-scroll`);
                    
                    // 添加滚动事件监听器
                    container.addEventListener('scroll', function() {
                        // 检查是否滚动到底部（允许5px的误差）
                        const isAtBottom = this.scrollHeight - this.clientHeight <= this.scrollTop + 5;
                        
                        if (isAtBottom) {
                            // 如果滚动到底部，启用自动滚动
                            testUnits[unitId].autoScroll = true;
                            autoScrollCheckbox.checked = true;
                        } else {
                            // 如果不在底部，禁用自动滚动
                            testUnits[unitId].autoScroll = false;
                            autoScrollCheckbox.checked = false;
                        }
                    });
                });
            }
            
            // 绑定自动滚动复选框事件
            document.querySelectorAll('.auto-scroll').forEach(checkbox => {
                checkbox.addEventListener('change', function() {
                    const unitId = this.closest('.test-unit').id.split('-').pop();
                    testUnits[unitId].autoScroll = this.checked;
                    
                    // 如果启用了自动滚动，立即滚动到底部
                    if (this.checked) {
                        const logContainer = document.querySelector(`#test-unit-${unitId} .log-container`);
                        requestAnimationFrame(() => {
                            logContainer.scrollTop = logContainer.scrollHeight;
                        });
                    }
                });
            });
            
            // 在DOMContentLoaded事件的末尾调用初始化函数
            initLogScrollListeners();
            
            // 重置测试状态的函数
            function resetTestStatus(process_id) {
                // 发送请求重置测试状态
                fetch('/api/reset_test_status', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({ process_id: process_id }),
                })
                .then(response => response.json())
                .then(data => {
                    if (data.status !== 'success') {
                        console.error('重置测试状态失败:', data.message);
                    }
                })
                .catch(error => {
                    console.error('重置测试状态请求出错:', error);
                });
            }
            
            // 绑定开始测试按钮事件
            document.querySelectorAll('.start-btn').forEach(button => {
                button.addEventListener('click', function() {
                    const unitId = this.getAttribute('data-unit-id');
                    const unit = document.getElementById(`test-unit-${unitId}`);
                    
                    // 获取测试参数
                    const repoType = unit.querySelector('.repo-type').value;
                    const sdkVersion = unit.querySelector('.sdk-version').value;
                    const releaseMode = unit.querySelector('.release-mode').value;
                    
                    // 如果选择了特定库，则获取已选库
                    let specificLibrary = null;
                    if (repoType === 'specific') {
                        specificLibrary = unit.querySelector('.selected-lib').value;
                        if (!specificLibrary) {
                            alert('请先搜索并选择库');
                            return;
                        }
                    }
                    
                    // 禁用开始按钮
                    this.disabled = true;
                    this.textContent = '正在启动...';
                    
                    // 显示状态信息和日志区域
                    unit.querySelector('.status-info').style.display = 'block';
                    unit.querySelector('.log-controls').style.display = 'flex';
                    unit.querySelector('.log-container').style.display = 'block';
                    
                    // 更新状态信息
                    unit.querySelector('.status-repo-type').textContent = repoType;
                    unit.querySelector('.status-progress').textContent = '0/0';
                    unit.querySelector('.status-current-lib').textContent = '-';
                    
                    // 重置进度条
                    const progressFill = unit.querySelector('.progress-fill');
                    progressFill.style.width = '0%';
                    progressFill.classList.remove('inactive');
                    
                    // 清空日志
                    const logContainer = unit.querySelector('.log-container');
                    logContainer.innerHTML = '<p class="log-line">正在启动测试...</p>';
                    
                    // 发送开始测试请求
                    fetch('/api/start_test', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({
                            repo_type: repoType,
                            sdk_version: sdkVersion,
                            release_mode: releaseMode,
                            specific_library: specificLibrary
                        }),
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data.status === 'success') {
                            // 保存进程ID
                            testUnits[unitId].processId = data.process_id;
                            testUnits[unitId].running = true;
                            testUnits[unitId].logIndex = 0;
                            
                            // 显示停止按钮
                            unit.querySelector('.stop-btn').style.display = 'block';
                            
                            // 开始定时更新状态
                            startStatusUpdates(unitId);
                        } else {
                            // 启动失败，恢复按钮状态
                            this.disabled = false;
                            this.textContent = '开始测试';
                            logContainer.innerHTML += `<p class="log-line">启动测试失败: ${data.message}</p>`;
                        }
                    })
                    .catch(error => {
                        // 请求出错，恢复按钮状态
                        this.disabled = false;
                        this.textContent = '开始测试';
                        logContainer.innerHTML += `<p class="log-line">请求出错: ${error.message}</p>`;
                    });
                });
            });
            
            // 绑定停止按钮事件
            document.querySelectorAll('.stop-btn').forEach(button => {
                button.addEventListener('click', function() {
                    const unitId = this.closest('.test-unit').id.split('-').pop();
                    const processId = testUnits[unitId].processId;
                    
                    if (!processId) {
                        alert('没有正在运行的测试');
                        return;
                    }
                    
                    // 禁用按钮，防止重复点击
                    this.disabled = true;
                    this.textContent = '正在停止...';
                    
                    // 发送停止请求
                    fetch('/api/stop_test', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                        },
                        body: JSON.stringify({ process_id: processId }),
                    })
                    .then(response => response.json())
                    .then(data => {
                        if (data.status === 'success') {
                            // 停止成功，更新UI
                            testUnits[unitId].running = false;
                            clearInterval(testUnits[unitId].intervalId);
                            
                            // 更新按钮状态
                            const unit = document.getElementById(`test-unit-${unitId}`);
                            unit.querySelector('.start-btn').disabled = false;
                            unit.querySelector('.start-btn').textContent = '开始测试';
                            
                            // 隐藏停止按钮，而不是仅重置状态
                            this.style.display = 'none';
                            this.disabled = false;
                            this.textContent = '停止测试';
                            
                            unit.querySelector('.progress-fill').classList.add('inactive');
                            
                            // 添加停止信息到日志
                            const logContainer = unit.querySelector('.log-container');
                            const logLine = document.createElement('p');
                            logLine.className = 'log-line';
                            logLine.textContent = '测试已被用户停止';
                            logContainer.appendChild(logLine);
                            
                            if (testUnits[unitId].autoScroll) {
                                logContainer.scrollTop = logContainer.scrollHeight;
                            }
                        } else {
                            // 停止失败，恢复按钮状态
                            this.disabled = false;
                            this.textContent = '停止测试';
                            alert(`停止测试失败: ${data.message}`);
                        }
                    })
                    .catch(error => {
                        // 请求出错，恢复按钮状态
                        this.disabled = false;
                        this.textContent = '停止测试';
                        alert(`请求出错: ${error.message}`);
                    });
                });
            });
            
            // 绑定清理日志按钮事件
            document.querySelectorAll('.clear-log-btn').forEach(button => {
                button.addEventListener('click', function() {
                    const unitId = this.closest('.test-unit').id.split('-').pop();
                    const logContainer = document.getElementById(`test-unit-${unitId}`).querySelector('.log-container');
                    
                    if (confirm('确定要清空所有日志吗？')) {
                        logContainer.innerHTML = '<p class="log-line">日志已清空...</p>';
                        testUnits[unitId].logIndex = 0;
                    }
                });
            });
            
            // 绑定放大日志按钮事件
            document.querySelectorAll('.expand-log-btn').forEach(button => {
                button.addEventListener('click', function() {
                    const unitId = this.closest('.test-unit').id.split('-').pop();
                    const logContainer = document.querySelector(`#test-unit-${unitId} .log-container`);
                    
                    logContainer.classList.toggle('expanded');
                    this.textContent = logContainer.classList.contains('expanded') ? '缩小日志' : '放大日志';
                    
                    // Scroll to bottom if expanded
                    if (logContainer.classList.contains('expanded')) {
                        logContainer.scrollTop = logContainer.scrollHeight;
                    }
                });
            });
            
            // 绑定下载日志按钮事件
            document.querySelectorAll('.download-log-btn').forEach(button => {
                button.addEventListener('click', function() {
                    const unitId = this.closest('.test-unit').id.split('-').pop();
                    const processId = testUnits[unitId].processId;
                    
                    if (!processId) {
                        alert('没有可下载的日志');
                        return;
                    }
                    
                    // 获取日志内容
                    const logContainer = document.getElementById(`test-unit-${unitId}`).querySelector('.log-container');
                    const logLines = Array.from(logContainer.querySelectorAll('.log-line')).map(line => line.textContent);
                    const logText = logLines.join('\n');
                    
                    // 创建下载链接
                    const blob = new Blob([logText], { type: 'text/plain' });
                    const url = URL.createObjectURL(blob);
                    const a = document.createElement('a');
                    a.href = url;
                    const dateStr = new Date().toISOString().replace(/[:.]/g, '-');
                    a.download = `test_log_${processId.substring(0, 8)}_${dateStr}.txt`;
                    document.body.appendChild(a);
                    a.click();
                    document.body.removeChild(a);
                    URL.revokeObjectURL(url);
                });
            });
        });
    </script>
</body>
</html>
